
#include "flash_if.h"




void FLASH_If_Init(void)
{
	HAL_FLASH_Unlock();
	
	__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGAERR | FLASH_FLAG_WRPERR);
	
	HAL_FLASH_Lock();
}

uint32_t FLASH_If_Erase(uint32_t start , uint32_t page_num)
{
	uint32_t PageError = 0;
    uint32_t PageStart = 0;
    FLASH_EraseInitTypeDef pEraseInit;
    HAL_StatusTypeDef status = HAL_OK;

    HAL_FLASH_Unlock();

    PageStart = (start - FLASH_START_ADDR) / FLASH_PAGE_SIZE;

    pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
    pEraseInit.Page = PageStart;
    pEraseInit.NbPages = page_num;
    pEraseInit.Banks = FLASH_BANK_1;
    status = HAL_FLASHEx_Erase(&pEraseInit,&PageError);

    HAL_FLASH_Lock();

    return status;
}

uint32_t FLASH_If_Write(uint32_t flash_addr, uint64_t *p_source, uint32_t length)
{
	int i = 0;
	uint32_t rc = FLASH_WRITE_SUCCESS;
	
	HAL_FLASH_Unlock();
	
	for (i = 0; i < length; i++)
	{
		if (flash_addr >= FLASH_END_ADDR)
		{
			rc = FLASH_WRITE_ADDR_EXCEED;
			break;
		}
		
		if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, flash_addr, p_source[i]) == HAL_OK)
		{
			 if (*(uint64_t *)flash_addr != p_source[i])
			 {
				 rc = FLASH_WRITE_DATA_VERIFY_FAIL;
				 break;
			 }
			 flash_addr += sizeof(uint64_t);
		}
		else
		{
			 rc = FLASH_WRITE_PROGRAM_FAIL;
			 break;
		}
	}
	
	HAL_FLASH_Lock();
	
	return rc;
}
